昨天既然都提到 self-hosted runner 了,在繼續下一個部分前,我們插入其他話題,來玩一些跟 runner 相關的內容吧。
正好我服務的公司準備推動一個全集團共用的版控系統,也就是 GitHub Enterprise,而我不幸地被 assign 這個任務,內部要跑資安審核那些有的沒有的官僚流程以外,架構規劃、技術評估也是我來用。更麻煩的是還要跟內部其他部門、海外分公司同仁溝通試用期間發生的問題,所幸有人陪我分擔。
公司用的版控系統很雜,而我所在的部門目前用 GitLab,而且透過 CI/CD 來部署應用程式到測試區。當初因為不想要架 Jenkins,因此採用 GitLab CI/CD Pipelines 來執行 CI/CD 作業。現在隨著版控系統變更,而我所在部門因為主導引入 GitHub Enterprise,勢必得身先士卒改用 GitHub Enterprise,導致 CI/CD 也被迫得轉去用 GitHub Actions(這時候用 Jenkins 的人應該笑得很大聲)。
參加鐵人賽的當下,我正在想要怎麼 porting 原有的 CI/CD pipeline 過去,我們過去是採用「runner 在 container 內、job 也在獨立的 container 內執行」的執行模式,如果 GitHub 有一樣的模式可以照搬,那就可以省很多功夫在 porting 上。
我評估了一下,執行 CI/CD job 的方式若以「是否採用容器化技術」來做區別的話,有 4 種組合:
run:
) 給弄亂今天先來玩看看 2.,也就是讓 runner 位於 container 內。
我們求速成,使用 https://github.com/myoung34/docker-github-actions-runner 提供的 image 進行部署,確認此法是否可行
首先參考官方文件,先請一個權限夠大的人(通常就是管理員啦)建立一個 personal access token (classic)
根據官方文件,勾選以下權限
然後 SSH 進去要安裝 runner 的機器,建立一個 ephemeral-github-actions-runner.env
檔案,把剛剛建立的 token 填入 ACCESS_TOKEN
(如果你是要給整個 organization 甚至是 enterprise 共用的話就看情況修改):
# Install with:
# sudo install -m 600 ephemeral-github-actions-runner.env /etc/
RUNNER_SCOPE=repo
REPO_URL=https://github.com/your-org/your-repo
# Alternate for org scope:
#RUNNER_SCOPE=org
#ORG_NAME=your-org
LABELS=any-custom-labels-go-here
ACCESS_TOKEN=foo-access-token
RUNNER_WORKDIR=/tmp/runner/work
DISABLE_AUTO_UPDATE=1
EPHEMERAL=1
根據官方文件建立 systemd service unit 檔案,照抄即可,該 service 啟動時會動態去抓 ephemeral-github-actions-runner.env
的設定
# Install with:
# sudo install -m 644 ephemeral-github-actions-runner.service /etc/systemd/system/
# sudo systemctl daemon-reload
# sudo systemctl enable ephemeral-github-actions-runner
# Run with:
# sudo systemctl start ephemeral-github-actions-runner
# Stop with:
# sudo systemctl stop ephemeral-github-actions-runner
# See live logs with:
# journalctl -f -u ephemeral-github-actions-runner.service --no-hostname --no-tail
[Unit]
Description=Ephemeral GitHub Actions Runner Container
After=docker.service
Requires=docker.service
[Service]
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/docker stop %N
ExecStartPre=-/usr/bin/docker rm %N
ExecStartPre=-/usr/bin/docker pull myoung34/github-runner:latest
ExecStart=/usr/bin/docker run --rm \
--env-file /etc/ephemeral-github-actions-runner.env \
-e RUNNER_NAME=%H \
-v /var/run/docker.sock:/var/run/docker.sock \
--name %N \
myoung34/github-runner:latest
[Install]
WantedBy=multi-user.target
安裝新的 container 形式執行的 GitHub Actions self-hosted Runner:
root@pi-host:/home/user# sudo install -m 600 ephemeral-github-actions-runner.env /etc/
root@pi-host:/home/user# sudo install -m 644 ephemeral-github-actions-runner.service /etc/systemd/system/
root@pi-host:/home/user# systemctl daemon-reload
systemctl enable ephemeral-github-actions-runner
root@pi-host:/home/user# systemctl enable ephemeral-github-actions-runner
Created symlink /etc/systemd/system/multi-user.target.wants/ephemeral-github-actions-runner.service → /etc/systemd/system/ephemeral-github-actions-runner.service.
root@pi-host:/home/user# systemctl start ephemeral-github-actions-runner
root@pi-host:/home/user# journalctl -f -u ephemeral-github-actions-runner.service --no-hostname --no-tail
Sep 20 21:40:27 systemd[1]: Starting ephemeral-github-actions-runner.service - Ephemeral GitHub Actions Runner Container...
Sep 20 21:40:27 docker[1976898]: Error response from daemon: No such container: ephemeral-github-actions-runner
Sep 20 21:40:27 docker[1976906]: Error response from daemon: No such container: ephemeral-github-actions-runner
Sep 20 21:40:31 docker[1976912]: latest: Pulling from myoung34/github-runner
Sep 20 21:40:31 docker[1976912]: 82d728d38b98: Already exists
... 省略 ...
Sep 20 21:42:57 docker[1976912]: 501117f7dad0: Pull complete
Sep 20 21:42:57 docker[1976912]: Digest: sha256:63f0d343951e0c998fd756b65cccd1602f15ba79e96f857d05023c5d0bb82833
Sep 20 21:42:57 docker[1976912]: Status: Downloaded newer image for myoung34/github-runner:latest
Sep 20 21:42:57 docker[1976912]: docker.io/myoung34/github-runner:latest
Sep 20 21:42:57 systemd[1]: Started ephemeral-github-actions-runner.service - Ephemeral GitHub Actions Runner Container.
Sep 20 21:43:00 docker[1978373]: Runner reusage is disabled
Sep 20 21:43:00 docker[1978373]: Obtaining the token of the runner
Sep 20 21:43:01 docker[1978373]: Ephemeral option is enabled
Sep 20 21:43:01 docker[1978373]: Disable auto update option is enabled
Sep 20 21:43:01 docker[1978373]: Configuring
Sep 20 21:43:02 docker[1978373]: --------------------------------------------------------------------------------
Sep 20 21:43:02 docker[1978373]: | ____ _ _ _ _ _ _ _ _ |
Sep 20 21:43:02 docker[1978373]: | / ___(_) |_| | | |_ _| |__ / \ ___| |_(_) ___ _ __ ___ |
Sep 20 21:43:02 docker[1978373]: | | | _| | __| |_| | | | | '_ \ / _ \ / __| __| |/ _ \| '_ \/ __| |
Sep 20 21:43:02 docker[1978373]: | | |_| | | |_| _ | |_| | |_) | / ___ \ (__| |_| | (_) | | | \__ \ |
Sep 20 21:43:02 docker[1978373]: | \____|_|\__|_| |_|\__,_|_.__/ /_/ \_\___|\__|_|\___/|_| |_|___/ |
Sep 20 21:43:02 docker[1978373]: | |
Sep 20 21:43:02 docker[1978373]: | Self-hosted runner registration |
Sep 20 21:43:02 docker[1978373]: | |
Sep 20 21:43:02 docker[1978373]: --------------------------------------------------------------------------------
Sep 20 21:43:02 docker[1978373]: # Authentication
Sep 20 21:43:08 docker[1978373]: √ Connected to GitHub
Sep 20 21:43:08 docker[1978373]: # Runner Registration
Sep 20 21:43:09 docker[1978373]: √ Runner successfully added
Sep 20 21:43:12 docker[1978373]: √ Runner connection is good
Sep 20 21:43:12 docker[1978373]: # Runner settings
Sep 20 21:43:12 docker[1978373]: √ Settings Saved.
Sep 20 21:43:12 docker[1978373]: mkdir: cannot create directory ‘/tmp/runner/work’: No such file or directory
Sep 20 21:43:18 docker[1978373]: √ Connected to GitHub
Sep 20 21:43:20 docker[1978373]: Current runner version: '2.309.0'
Sep 20 21:43:20 docker[1978373]: 2023-09-20 13:43:20Z: Listening for Jobs
看到 "Connected to GitHub" 了,安裝成功
現在我們停掉前一天建立的 runner service
root@pi-host:/home/user# systemctl stop actions.runner.**masked**-too-simple-rss-reader.pi4.service
去 GitHub runner 頁面看一下,可以看到昨天設定的 runner 已經下線、新的上線了。
來重跑一下 Day 17 的 workflow 試試...
成功了,而且可以看到 Runner name 是新的 runner 的名字
今天的實驗證明 runner 是可以在 container 內執行的,明天我們來看一下 workflow 的 job 是否可以在 container 內執行。